/*
 * pn.h
 *
 *  Created on: 25.04.2012
 *      Author: g.kruglov
 */

#ifndef PN_H_
#define PN_H_

#include <avr/io.h>
#include "pn_defins.h"

typedef enum {csCardOk, csCardOut, csCardError, csCardHalted} CardState_t;

class Card_t {
public:
    CardState_t State;
    uint8_t *Data;
    uint16_t DataLength;
    uint8_t ID[7];
    bool ReadID(void);
};

extern Card_t Card;

typedef void(*ftVoid_Void)(void);

#define PN_PORT         PORTD
#define PN_DDR          DDRD
#define PN_PIN          PIND
#define PN_NSS_PIN      PD1
#define PN_MISO_PIN     PD2
#define PN_MOSI_PIN     PD3
#define PN_RESET_PIN    PD4
#define PN_SCK_PIN      PD5
#define PN_IRQ_PIN      PD6

#define PN_NSS_HI()         PN_PORT |=  (1<<PN_NSS_PIN)
#define PN_NSS_LO()         PN_PORT &= ~(1<<PN_NSS_PIN)
#define PN_MOSI_HI()        PN_PORT |=  (1<<PN_MOSI_PIN)
#define PN_MOSI_LO()        PN_PORT &= ~(1<<PN_MOSI_PIN)
#define PN_SCK_HI()         PN_PORT |=  (1<<PN_SCK_PIN)
#define PN_SCK_LO()         PN_PORT &= ~(1<<PN_SCK_PIN)
#define PN_RESET_HI()       PN_PORT |=  (1<<PN_RESET_PIN)
#define PN_RESET_LO()       PN_PORT &= ~(1<<PN_RESET_PIN)
#define PN_REPLY_IS_READY() bit_is_clear(PN_PIN, PN_IRQ_PIN)
#define PN_MISO_IS_HI()     bit_is_set(PN_PIN, PN_MISO_PIN)


enum PN_PktRslt_t {pnPktACK, pnPktErrFrame, pnPktOk, pnPktFail, pnPktCRC};

class PN_t {
private:
    uint8_t Buf[264];
    uint16_t Length;
    uint16_t Timer;
    uint8_t WriteReadByte(uint8_t AByte);
    uint8_t hw_WriteReadByte(uint8_t);
    void WritePkt(void);
    PN_PktRslt_t ReadPkt(void);
    PN_PktRslt_t WriteAndWaitReply(void);
    PN_PktRslt_t WriteAndWaitData(void);
    PN_PktRslt_t Cmd(uint8_t ACmd, uint16_t ALength, ...);
    // Hi-level
    void FieldOn(void)  { Cmd(PN_CMD_RF_CONFIGURATION, 2, 0x01, 0x01); } // Cfg=0x01=RF field, value=0x01=FieldOn
    void FieldOff(void) { Cmd(PN_CMD_RF_CONFIGURATION, 2, 0x01, 0x00); } // Cfg=0x01=RF field, value=0x00=FieldOff
    // Card
    bool CardIsAppeared(void);
    bool CheckIfCardStillNear(void);
public:
    void Task(void);
    void Init(void);
    bool MifareRead(uint8_t *ABuf, uint8_t AAddr); // Reads 16 bytes of Mifare data into ABuf
    // Events
    ftVoid_Void Evt_CardAppeared;
};

extern PN_t Pn;

#endif /* PN_H_ */
